﻿package com._public._ui 
{
	import com._public._display.Pen;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.NetStatusEvent;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.setTimeout;
	import flash.utils.Timer;
	
	/**
	 * ...
	 * @author DefaultUser (Tools -> Custom Arguments...)
	 * 例子：
	 *  import com._public._ui.FLVPlayer;
		var player:FLVPlayer = new FLVPlayer();
		addChild(player);
		player.url = "gb.flv";
		player.addEventListener(FLVPlayer.PAUSE,flvPause);
		player.addEventListener(FLVPlayer.PLAY,flvPlay);
		player.addEventListener(Event.COMPLETE,flvComplete);
		player.addEventListener(FLVPlayer.START,startFlv);
		player.addEventListener(Event.CLOSE,flvClose);
		player.addEventListener(FLVPlayer.STOP,flvStop);
		player.palyFlv();
		function flvPause(evt:Event):void {
			trace("stop..");
		}
		function flvPlay(evt:Event):void {
			trace("play..");
		}
		function startFlv(evt:Event):void {
			trace("flv start");
		}
		function flvComplete(evt:Event):void {
			trace("flv complete");
		}
		function flvClose(evt:Event):void {
			trace("flv close");
		}
		function flvStop(evt:Event):void {
			trace("flv stop");
		}
	 */
	public class FLVPlayer extends Sprite
	{
		private var skipInit:Boolean;
		private var _url:String;
		private var _controlBar:Sprite;
		private var _playBtn:Sprite;
		private var _stopBtn:Sprite;
		private var _progressBar:Sprite;
		private var _dragBar:Sprite;
		private var _time:TextField;
		private var _netStream:NetStream;
		private var _conn:NetConnection;
		private var _distance:int = 10;
		private var _video:Video;
		
		private var _duration:int = 0;
		
		private var _dragRect:Rectangle;
		
		private var _playing:Boolean = false;
		
		private var _timer:Timer;
		private var _loaded:Boolean = true;
		//--------------style------------------
		private var _lineColor:uint = 0;
		private var _lineAlpha:Number = 0;
		private var _bgAlpha:Number = 0.5;
		private var _bgWid:Number = 410;
		private var _bgHei:Number = 310;
		private var _barColor:uint = 0xffffff;
		private var _barAlpha:Number = 0.6;
		private var _barHei:Number = 20;
		private var _playColor:uint = 0;
		private var _playAlpha:Number = 1;
		private var _stopColor:uint = 0;
		private var _stopAlpha:Number = 1;
		private var _proBarHei:Number = 2;
		private var _proBarColor:uint = 0xffffff;
		private var _progressColor:uint = 0x993333;
		private var _proBarAlpha:Number = 0.5;
		private var _dragBarColor:uint = 0;
		private var _dragBarAlpha:Number = 0.5;
		
		private var _timerWid:int = 70;
		private var _timeColor:uint = 0;
		
		//-------------------event----------------------
		public static const STOP:String = "stop";
		public static const PLAY:String = "play";
		public static const PAUSE:String = "pause";
		public static const START:String = "flvStart";
		public function FLVPlayer(url:String="") 
		{
			_url = url;
			createSkin()
		}
		override public function get width():Number { return _bgWid; }
		
		override public function set width(value:Number):void 
		{
			_bgWid = value;
			createSkin();
		}
		override public function get height():Number { return _bgHei; }
		
		override public function set height(value:Number):void 
		{
			_bgHei = value;
			createSkin();
		}
		public function set url(value:String):void
		{
			_url = value;
		}
		public function get url():String
		{
			return _url;
		}
		private function createSkin():void
		{			
			if(!skipInit)_controlBar = new Sprite;
			_controlBar.graphics.clear();
			_controlBar.graphics.beginFill(_barColor, _barAlpha);
			_controlBar.graphics.drawRoundRect(0, 0, width, _barHei,5,5);
			_controlBar.graphics.endFill();
			
			if(!skipInit){
			_playBtn = new Sprite;
			var pen:Pen = new Pen(_playBtn.graphics);
			pen.lineStyle(0, 0);
			pen.beginFill(_playColor,_playAlpha);
			pen.drawTriangle(0, 0, _barHei * .7, _barHei * .7, 60);//画等边三角形
			
			_stopBtn = new Sprite;
			_stopBtn.graphics.beginFill(_stopColor, _stopAlpha);
			_stopBtn.graphics.drawRect(0, 0, _barHei * .7, _barHei * .7);
			_stopBtn.graphics.endFill();
			_progressBar = new Sprite;
			
			_dragBar = new Sprite;
			_dragBar.graphics.beginFill(_dragBarColor, _dragBarAlpha);
			_dragBar.graphics.drawRect(0, 0, _barHei * 0.3, _barHei * 0.6);
			_dragBar.graphics.endFill();
			
			_time = new TextField;
			_time.defaultTextFormat=new TextFormat("Arial", 9,0x666666);
			_time.autoSize = "left";
			_time.text = "00:00 / 00:00";
			_time.mouseEnabled = false;
			_time.textColor = _timeColor;
			
			_playBtn.rotation = 30;
			_stopBtn.buttonMode = _dragBar.buttonMode = _playBtn.buttonMode = true;
			_playBtn.x = _distance;
			_controlBar.addChild(_time);
			_controlBar.addChild(_playBtn);
			_controlBar.addChild(_progressBar);
			_controlBar.addChild(_dragBar);
			this.addChild(_controlBar);
			}
			_playBtn.y = (_barHei - _barHei * .7) * .5;
			
			_progressBar.graphics.clear();
			_progressBar.graphics.lineStyle(_proBarHei, _proBarColor, _proBarAlpha);
			_progressBar.graphics.lineTo(width - _distance * 3 - _barHei * .7 * 0.75 - _timerWid, 0);
			
			_controlBar.y = _bgHei - _barHei;
			_controlBar.x = (_bgWid - width) * .5;
			
			
			_progressBar.y = _barHei * .5;
			_dragBar.x = _progressBar.x = _distance * 2 + _barHei * .7 * 0.75;
			
			_dragBar.y = (_barHei - _dragBar.height) * .5;
			
			_time.x = _progressBar.x + _progressBar.width + _distance * .5;
			
			_dragRect = new Rectangle(_dragBar.x, _dragBar.y, _progressBar.width - _dragBar.width, 0);
			addControlListen();
			skipInit = true;
			
			if (_video) {
				_video.width = width;
				_video.height = height;
				}
		}
		public function palyFlv():void
		{
			_conn = new NetConnection();
			_conn.connect(null);
			_netStream = new NetStream(_conn);
			_netStream.play(_url);
			_video = new Video(width,height);
			var client:Object = new Object();
			client.onMetaData = onMetaData;
			_netStream.client = client;
			_video.attachNetStream(_netStream);
			_video.x = _video.y = 5;
			this.addChildAt(_video, 0);
			_playing = true;
			_stopBtn.x = _playBtn.x;
			_stopBtn.y = _playBtn.y;
			if (_playBtn.parent)
			{
				_controlBar.removeChild(_playBtn);
			}
			_controlBar.addChild(_stopBtn);
			this.dispatchEvent(new Event(FLVPlayer.START));
			_netStream.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
			_timer = new Timer(200);
			_timer.addEventListener(TimerEvent.TIMER, onEnter);
			_timer.start();
		}
		private function onStatus(evt:NetStatusEvent):void
		{
			//trace(evt.info.code);
		}
		private function connectStream():void
		{
			
		}
		private function flvComplete(evt:NetStatusEvent):void
		{
			
		}
		private function onEnter(evt:TimerEvent):void
		{
			if (_duration > 0 && _netStream.time > 0)
			{
				var time:int = _netStream.time;
				_time.text = replaceStr(time) + " / " + replaceStr(_duration);
				_dragBar.x = _progressBar.x + (time / _duration) * (_progressBar.width - _dragBar.width);
				if (time == _duration)
				{
					//播放完成.
					this.dispatchEvent(new Event(Event.COMPLETE));
					_timer.removeEventListener(TimerEvent.TIMER, onEnter);
				}
			}
			if (_loaded)
			{
				var num:Number = _netStream.bytesLoaded / _netStream.bytesTotal;
				_progressBar.graphics.lineStyle(_proBarHei, _progressColor, _proBarAlpha);
				_progressBar.graphics.moveTo(0, 0);
				_progressBar.graphics.lineTo((width - _distance * 3 - _barHei * .7 * 0.75 - _timerWid) * num, 0);
				if (num == 1)
				{
					_loaded = false;
				}
			}
		}
		private function replaceStr(time:int):String
		{
			var minute:String = "";
			var second:String = "";
			if (String(int(time / 60)).length > 1)
			{
				minute = String(int(time / 60));
			}else
			{
				minute = "0" + String(int(time / 60));
			}
			if (String(time % 60).length > 1)
			{
				second = String(time % 60)
			}else
			{
				second = "0" + String(time % 60);
			}
			return minute + ":" + second;
		}
		private function onMetaData(data:Object):void
		{
			_duration = data.duration;
		}
		private function addControlListen():void
		{
			_dragBar.addEventListener(MouseEvent.MOUSE_DOWN, beginDrag);
			_playBtn.addEventListener(MouseEvent.CLICK, playHangler);
			_stopBtn.addEventListener(MouseEvent.CLICK, stopHangler);
		}
		private function playHangler(evt:MouseEvent):void
		{
			play();
		}
		private function stopHangler(evt:MouseEvent):void
		{
			pause();
		}
		private function beginDrag(evt:MouseEvent):void
		{
			_dragBar.startDrag(false, _dragRect);
			this.stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
			_timer.removeEventListener(TimerEvent.TIMER, onEnter);
			this.stage.addEventListener(Event.ENTER_FRAME, dragEnter);
		}
		private function dragEnter(evt:Event):void
		{
			var time:int = (_dragBar.x - _progressBar.x) / (_progressBar.width - _dragBar.width) * _duration;
			_time.text = replaceStr(time) + " / " + replaceStr(_duration);
		}
		private function endDrag(evt:MouseEvent):void
		{
			_dragBar.stopDrag();
			this.stage.removeEventListener(MouseEvent.MOUSE_UP, endDrag);
			this.stage.removeEventListener(Event.ENTER_FRAME, dragEnter);
			var time:int = (_dragBar.x - _progressBar.x) / (_progressBar.width - _dragBar.width) * _duration;
			_netStream.seek(time);
			setTimeout(addListen, 100);
		}
		private function addListen():void
		{
			_timer.addEventListener(TimerEvent.TIMER, onEnter);
		}
		public function play():void
		{
			if (!_playing&&_netStream!=null)
			{
				_netStream.resume();
				_stopBtn.x = _playBtn.x;
				_stopBtn.y = _playBtn.y;
				_controlBar.removeChild(_playBtn);
				_controlBar.addChild(_stopBtn);
				_playing = !_playing;
				this.dispatchEvent(new Event(FLVPlayer.PLAY));
			}
		}
		public function stop():void
		{
			if (_netStream != null && _netStream.time > 0)
			{
				_netStream.seek(0);
				this.dispatchEvent(new Event(FLVPlayer.STOP));
				if (_playing)
				{
					_netStream.pause();
					_playBtn.x = _stopBtn.x;
					_playBtn.y = _stopBtn.y;
					_controlBar.removeChild(_stopBtn);
					_controlBar.addChild(_playBtn);
					_playing = !_playing;
					_time.text = replaceStr(0) + " / " + replaceStr(_duration);
					_dragBar.x = _progressBar.x;
				}
			}
		}
		public function pause():void
		{
			if (_playing&&_netStream!=null)
			{
				_netStream.pause();
				_playBtn.x = _stopBtn.x;
				_playBtn.y = _stopBtn.y;
				_controlBar.removeChild(_stopBtn);
				_controlBar.addChild(_playBtn);
				_playing = !_playing;
				this.dispatchEvent(new Event(FLVPlayer.PAUSE));
			}
		}
		public function close():void
		{
			if (_netStream!=null)
			{
				_timer.removeEventListener(TimerEvent.TIMER, onEnter);
				_video.clear();
				removeChild(_video);
				_conn.close();
				_netStream.close();
				_time.text = "00:00 / 00:00";
				_dragBar.x = _progressBar.x;
				_netStream = null;
				_video = null;
				_conn = null;
				_timer = null;
				this.dispatchEvent(new Event(Event.CLOSE));
			}
		}
		public function set showControlBar(value:Boolean):void
		{
			if (value)
			{
				if (!_controlBar.parent)
				{
					this.addChild(_controlBar);
				}
			}else
			{
				if (_controlBar.parent)
				{
					this.removeChild(_controlBar);
				}
			}
		}
		public function printScreen():BitmapData
		{
			var bd:BitmapData = new BitmapData(_video.width, _video.height);
			bd.draw(_video);
			return bd;
		}
	}
	
}